<?php

namespace app\privatearea\controller\astro\v1;

use app\common\cachemodel\privatearea\PrivateAreaAstro;
use app\common\lib\IAuth;
use app\common\lib\Util;
use app\common\model\AppTelLogin;
use think\Cache;
use think\Controller;
use think\Db;
use think\Log;
use think\response\Json;

class Login extends Controller
{
    /**
     * 获取手机验证码
     * @return Json
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getCode()
    {
        $tel = input('tel/s', '');

        // 检查手机号是否正确
        if (!$tel || !Util::telRuleCheck($tel, 86))
        {
            return show(config('code.error'), '手机号错误');
        }

        $telStr = 'privatearea:astro:isSend:' . $tel;
        $isSendCode = Cache::get($telStr, false);
        if ($isSendCode)
        {
            return show(config('code.error'), '操作频繁，请稍后再试～');
        }

        $time = time();// 当前时间  有效时间暂定为十分钟 600s

        $expire = 600;

        $ip = $this->request->ip();

        try
        {
            $data = (new AppTelLogin())->where(['tel' => $tel, 'expire_time' => ['>', $time]])->findOrFail()->toArray();
        }
        catch (\Exception $e)
        {
            $data = [];
        }
        // 十分钟内无已有验证码
        if (empty($data))
        {
            $code = random_int(100000, 999999);// 六位验证码

            $expire_time = $time + $expire;
            try
            {
                Db::table('app_tel_login')->insertGetId([
                    'tel' => "$tel",
                    'create_time' => $time,
                    'expire_time' => $expire_time,
                    'code' => $code,
                ]);
            }
            catch (\Exception $e)
            {
                Log::write('获取手机验证码失败：' . $e->getMessage() . PHP_EOL . '失败行数：' . $e->getLine() . PHP_EOL . '错误文件：【' . $e->getFile() . '】');
                return show(config('code.error'), '发送失败');
            }

        } else
        {
            $code = $data['code'];
        }
        // 登录或绑定
        $result = Util::sendHySms([$tel], '', 49273, ['valid_code' => $code]);
        if (!$result['success'])
        {
            return show(config('code.error'), '发送失败');
        } else
        {
            // 缓存 验证码 10分钟
            Cache::set('privatearea:astro:tel_code:' . $tel, $code, 600);
        }
        Cache::set($telStr, true, 50);
        // 记录短信日志
        model('log')->save([
            'tel' => $tel,
            'ip' => $ip,
            'create_time' => $time,
            'type' => 1,
        ]);
        return show(config('code.success'), '发送成功');
    }


    public function login()
    {
        $tel = input('tel/s', '');
        $code = input('code/s', '');

        $appConfig = config('app');

        // 短信验证码 或 密码是否存在
        if (empty($code))
        {
            return show(config('code.error'), '手机短信验证码');
        }
        // 短信登录时，检测验证码是否正确
        if (!empty($code))
        {
            if (!in_array($tel, $appConfig['mobile'])
                || strpos($appConfig['code'] * (substr($tel, 3, 6)), $code) !== 0)
            {
                //  validate 严格校验
                $mobileCode = Cache::get('privatearea:astro:tel_code:' . $tel);
                if ($code != $mobileCode)
                {
                    return show(config('code.error'), '短信验证码错误');
                }
            }
        }

        $privateAreaUserModel = new PrivateAreaAstro();

        $privateAreaUserInfo = $privateAreaUserModel->where('telphone', $tel)->order('id desc')->find();

        if (!$privateAreaUserInfo)
        {
            return show(config('code.error'), '用户不存在～');
        }

        // 生成token  和 token到期时间
        $token = IAuth::setAppLoginToken($tel);
        $data = [
            'token' => $token,
            'token_expire' => strtotime("+" . $appConfig['login_time_out_day'] . " days"),
        ];

        // 更新 access_token过期时间
        $privateAreaUserModel->SavaData($privateAreaUserInfo['id'], $data);

        $privateAreaUid = $privateAreaUserInfo['id'];

        return show(config('code.success'), '登录成功', [
            'access_token' => $this->encryptWithOpenssl($data['token'] . '||' . $privateAreaUid)
        ]);
    }

    /**
     * 加密字符串
     * @param string $data 字符串
     * @return string
     */
    protected function encryptWithOpenssl($data): string
    {
        try
        {
            $config = config('privatearea');
            return base64_encode(openssl_encrypt($data, $config['aes_method'], $config['aes_key'], OPENSSL_RAW_DATA, $config['aes_iv']));
        }
        catch (\Exception $e)
        {
            return '';
        }

    }
}